/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wumpusworld;

import ArtificialAgent.AgentController;
import ArtificialAgent.ArtificialAgent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Hashtable;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 *
 * @author Macias
 */
public class ControlWindow extends JFrame{

ControlWindow cw =this;
JMenuBar menuBar;
JPanel welcomePanel;
JPanel playerPanel;
JPanel computerPanel;
    /**
     * canvas on which one can draw state of the game (map)
     */
    MyCanvas canvas;
    SmalllCanvas smallCanvas;
    /**
     * window on which "canvas" is drawn
     */
   public static MainWindow mainWindow;
    /**
     * game engine
     */
   WumpusEngine wumpusEngine;

    /**
     * key listener for two windows which allows controling game via keyboard
     */
    MyKeyListener keyListener;
    MyMouseMotionListener mouseMotionListener;
    ButtonGroup playerRBgroup;
    JRadioButtonMenuItem playerComp;
    public JCheckBox checkIfDynamicLearning ;
    public JCheckBox checkIfStepWorking = new JCheckBox("Step working");
    JButton bAgentStep;
    public JLabel resultsLabel ;
    public JSlider greedSlider;
    AgentController agentController;
    Thread thread;

    public PlotWindow plotWindow = new PlotWindow();
    ArrayList<Float> ratioData = new ArrayList<Float>();
    /**
     * Artificial Agent
     */
   public ArtificialAgent artificialAgent;

    ControlWindow(){
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        this.setSize(300,500);
        this.setLocation(710,10);
        this.setResizable(false);
        this.setTitle("Wumpus");
        this.setLayout(null);

        welcomePanel = new JPanel();
        welcomePanel.setSize(300,500);
        welcomePanel.setLayout(null);

        JLabel welcomeLabel= new JLabel("Welcome to the Wumpus World");
        welcomeLabel.setBounds(50,100,300,100);
        welcomePanel.add(welcomeLabel);
        this.add(welcomePanel);

        keyListener = new MyKeyListener(this,MyKeyListener.CONTROL_WINDOW);
        this.addKeyListener(keyListener);

        initPlayerPanel();
        initComputerPanel();
        initComponents();
        this.add(playerPanel);
        this.add(computerPanel);
        
        
        //TO dodal JEDREK - test agenta
        artificialAgent = new ArtificialAgent(wumpusEngine);
        artificialAgent.createNet(2);
//        artificialAgent.teach(new MapGenerator().generateTeachingSet(100, 2));

        agentController = null;
    }

    private void initComponents() {
        menuBar = new JMenuBar();
        JMenu gameMenu = new JMenu("Game");
        JMenu optionsMenu = new JMenu("Options");

        JMenuItem menuNewGame = new JMenuItem("New Game   F2");
        gameMenu.add(menuNewGame);
        menuNewGame.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                performNewGame();
            }


        });
//        this.add(playerPanel);
//        welcomePanel.setVisible(false);

        JMenu menuPlayer = new JMenu("Player");
        playerRBgroup = new ButtonGroup();
        JRadioButtonMenuItem playerHuman = new JRadioButtonMenuItem("Human");
        playerComp = new JRadioButtonMenuItem("Computer");

        menuPlayer.add(playerHuman);
        menuPlayer.add(playerComp);
        playerRBgroup.add(playerHuman);
        playerRBgroup.add(playerComp);
        playerComp.doClick();

        gameMenu.add(menuPlayer);

        //options menu
        JMenuItem mItemMapOptions = new JMenuItem("Map Options");
        mItemMapOptions.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                MapOptionsWindow mapOptions = new MapOptionsWindow(wumpusEngine,cw);
                mapOptions.setVisible(true);
            }
        });
        optionsMenu.add(mItemMapOptions);


        final JCheckBox checkIfHints = new JCheckBox("Enable hints");
        checkIfHints.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                canvas.showHints=checkIfHints.isSelected();
            }
        });
        //#############for testing #############
//        checkIfHints.doClick();

        optionsMenu.add(checkIfHints);

        checkIfDynamicLearning = new JCheckBox("Enable dynamic learning");
//        checkIfDynamicLearning.addActionListener(new ActionListener() {
//
//            public void actionPerformed(ActionEvent e) {
//                canvas.showHints=checkIfHints.isSelected();
//            }
//        });
        checkIfDynamicLearning.doClick();

        checkIfStepWorking.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
               bAgentStep.setVisible(checkIfStepWorking.isSelected());
               agentController.pauseThread(false);
            }
        });




        optionsMenu.add(checkIfDynamicLearning);
        optionsMenu.add(checkIfStepWorking);

        menuBar.add(gameMenu);
        menuBar.add(optionsMenu);
        this.setJMenuBar(menuBar);

        wumpusEngine = new WumpusEngine();

    }

    private void initPlayerPanel() {
        playerPanel = new JPanel();
        playerPanel.setSize(300,500);
        playerPanel.setLayout(null);

        JButton bNorth = new JButton("North");
        bNorth.setBounds(100, 50, 100, 30);
        bNorth.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                performMoveNorth();
                requestFocus();
            }

        });
        playerPanel.add(bNorth);

        JButton bSouth = new JButton("South");
        bSouth.setBounds(100, 100, 100, 30);
        bSouth.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                performMoveSouth();
                requestFocus();
            }

        });
        playerPanel.add(bSouth);

        JButton bEast = new JButton("East");
        bEast.setBounds(200, 75, 100, 30);
        bEast.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                performMoveEast();
                requestFocus();
            }

        });
        playerPanel.add(bEast);

        JButton bWest = new JButton("West");
        bWest.setBounds(0, 75, 100, 30);
        bWest.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                performMoveWest();
                requestFocus();
            }


        });
        playerPanel.add(bWest);


        JButton bShoot = new JButton("Shoot");
        bShoot.setBounds(100,150,100,25);
        bShoot.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                performShoot();
            }
        });
        playerPanel.add(bShoot);

        smallCanvas = new SmalllCanvas(canvas, wumpusEngine);
        smallCanvas.setBounds(100, 200, 100, 100);
        smallCanvas.setVisible(true);

        playerPanel.add(smallCanvas);
        playerPanel.setVisible(false);

    }


    private void initComputerPanel(){
        computerPanel = new JPanel();
        computerPanel.setSize(300,500);
        computerPanel.setLayout(null);


        final JSlider slider = new JSlider();
        slider.setMaximum(1000);
        slider.setMinimum(20);
        slider.setValue(600);
        slider.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {
               AgentController.speed= slider.getValue();
               cw.requestFocus();
            }
        });
        Hashtable labelTable = new Hashtable();
        labelTable.put(new Integer(100), new JLabel("20 ms"));
        labelTable.put(new Integer(1000), new JLabel("1 sec"));
        slider.setLabelTable(labelTable);
        slider.setPaintLabels(true);

        slider.setBounds(50, 30, 200, 35);
        slider.setVisible(true);

        JLabel speedLabel = new JLabel("set delay");
        speedLabel.setBounds(10, 5, 100, 20);
        speedLabel.setVisible(true);

        JButton bStop = new JButton("Stop");
        bStop.setBounds(100, 100, 100, 20);
        bStop.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                agentController.stopThread();
                mainWindow.dispose();

                cw.requestFocus();
            }
        });
        bStop.setVisible(true);

        JButton bClear = new JButton("Clear");
        bClear.setBounds(100, 150, 100, 20);
        bClear.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                artificialAgent.createNet(2);
//                mainWindow.dispose();

                cw.requestFocus();
            }
        });
        bClear.setVisible(true);


        greedSlider = new JSlider();
        greedSlider.setMaximum(100);
        greedSlider.setMinimum(10);
        greedSlider.setValue(50);
        greedSlider.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {

            artificialAgent.moveCost=((float)(greedSlider.getValue())/(2f*canvas.map[0].length));
            cw.requestFocus();
            }
        });
        Hashtable greedLabelTable = new Hashtable();
        greedLabelTable.put(new Integer(10), new JLabel("less greedy"));
        greedLabelTable.put(new Integer(100), new JLabel("more greedy"));
        greedSlider.setLabelTable(greedLabelTable);
        greedSlider.setPaintLabels(true);

        greedSlider.setBounds(50, 200, 200, 50);
        greedSlider.setVisible(true);


        final JSlider courageSlider = new JSlider();
        courageSlider.setMaximum(200);
        courageSlider.setMinimum(20);
        courageSlider.setValue(50);
        courageSlider.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {

            artificialAgent.pitImportance = 220-courageSlider.getValue();
            artificialAgent.wumpusImportance = 220-courageSlider.getValue();
            cw.requestFocus();
            }
        });
        Hashtable courageLabelTable = new Hashtable();
        courageLabelTable.put(new Integer(20), new JLabel("less couraged"));
        courageLabelTable.put(new Integer(200), new JLabel("more couraged"));
        courageSlider.setLabelTable(courageLabelTable);
        courageSlider.setPaintLabels(true);

        courageSlider.setBounds(50, 250, 200, 80);
        courageSlider.setVisible(true);



        resultsLabel = new JLabel("win/lose ratio: 0 / 0 (0)");
        resultsLabel.setBounds(10, 350, 200, 20);
        resultsLabel.setVisible(true);

        JButton bClearResult = new JButton("clear");
        bClearResult.setBounds(200, 350, 80, 20);
        bClearResult.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                resultsLabel.setText("win/lose ratio: 0 / 0 (0)");
                artificialAgent.lostCount=0;
                artificialAgent.winCount=0;
                ratioData.clear();
                plotWindow.setData(ratioData);
                plotWindow.repaintCanvas();
            }
        });
        bClearResult.setVisible(true);

         JButton bPlotResult = new JButton("plot");
        bPlotResult.setBounds(200, 380, 80, 20);
        bPlotResult.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                plotWindow.setLocation(720, 100);
                plotWindow.setVisible(true);
                if(ratioData.size()>0)
                    plotWindow.setData(ratioData);
//                else{
//                    float[] tmp = new float[1];
//                    tmp[0]=0;
//                    plotWindow.setData(tmp);
//                }
                plotWindow.repaintCanvas();
            }
        });
        bPlotResult.setVisible(true);

        bAgentStep = new JButton("Step");
        bAgentStep.setBounds(100,400,80,20);
        bAgentStep.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                agentController.pauseThread(false);
            }
        });
        bAgentStep.setVisible(checkIfStepWorking.isSelected());

        computerPanel.add(bAgentStep);
        computerPanel.add(resultsLabel);
        computerPanel.add(bClearResult);
        computerPanel.add(bPlotResult);
        computerPanel.add(bClear);
        computerPanel.add(bStop);
        computerPanel.add(speedLabel);
        computerPanel.add(slider);
        computerPanel.add(greedSlider);
        computerPanel.add(courageSlider);
        
        computerPanel.setVisible(false);

    }


    public void performNewGame() {
        //closing old window if it exists
        if(mainWindow!=null) mainWindow.dispose();
//initialising new window and wumpus engine
        mainWindow = new MainWindow();
        canvas = new MyCanvas();
        canvas.setSize(mainWindow.getContentPane().getSize());
        mainWindow.add(canvas);
        mainWindow.setVisible(true);
        mainWindow.addKeyListener(keyListener);

//        mouseMotionListener = new MyMouseMotionListener(canvas,artificialAgent);
//        canvas.addMouseMotionListener(mouseMotionListener);

        
        wumpusEngine.setCanvas(canvas);
        wumpusEngine.init();

        mouseMotionListener = new MyMouseMotionListener(canvas,artificialAgent);
        canvas.addMouseMotionListener(mouseMotionListener);

        smallCanvas.setCanvas(canvas);
        smallCanvas.setEngine(wumpusEngine);

//        smallCanvas.setMap(wumpusEngine.getMap());
        smallCanvas.repaint();


        playerPanel.setVisible(!playerComp.isSelected());
        computerPanel.setVisible(playerComp.isSelected());

        if(playerComp.isSelected())
        {
            if(agentController!=null) agentController.stopThread();
            agentController = new AgentController(this);

            thread = new Thread(agentController);
            thread.start();
        }
        else agentController.stopThread();

        wumpusEngine.showNotifications = !playerComp.isSelected();
        wumpusEngine.disposeWin = !playerComp.isSelected();

        welcomePanel.setVisible(false);
                
            }

    public void performMoveNorth() {
            if(!playerComp.isSelected()){
                wumpusEngine.moveUp();
                smallCanvas.repaint();
                canvas.drawHint(-1,-1,-1,-1);   //stop drawing hints
                mouseMotionListener.oldPosX=-1; //condition so when mouse is moved hint will be repainted
            }
            
                }
    public void performMoveSouth() {
         if(!playerComp.isSelected()){
                wumpusEngine.moveDown();
                smallCanvas.repaint();
                canvas.drawHint(-1,-1,-1,-1);   //stop drawing hints
                mouseMotionListener.oldPosX=-1; //condition so when mouse is moved hint will be repainted
            }
            
                }
    public void performMoveEast() {
         if(!playerComp.isSelected()){
                wumpusEngine.moveRight();
                 smallCanvas.repaint();
                canvas.drawHint(-1,-1,-1,-1);   //stop drawing hints
                mouseMotionListener.oldPosX=-1; //condition so when mouse is moved hint will be repainted
            }
            
                }
    public void performMoveWest() {
         if(!playerComp.isSelected()){
                wumpusEngine.moveLeft();
                smallCanvas.repaint();
                canvas.drawHint(-1,-1,-1,-1);   //stop drawing hints
                mouseMotionListener.oldPosX=-1; //condition so when mouse is moved hint will be repainted
            }
            
                }
public void performShoot() {

    ShootDirectionWindow shootWindow = new ShootDirectionWindow(wumpusEngine);
    shootWindow.setLocation(100, 100);
    shootWindow.setVisible(true);
                canvas.drawHint(-1,-1,-1,-1);   //stop drawing hints
                mouseMotionListener.oldPosX=-1; //condition so when mouse is moved hint will be repainted
//    wumpusEngine.shoot(WumpusEngine.DIRECTION_DOWN);

//         if(!playerComp.isSelected()){
//                wumpusEngine.moveLeft();
//                smallCanvas.repaint();
//            }
//
                }
   
    public void closeGame() {
        mainWindow.removeKeyListener(keyListener);
        mainWindow.removeMouseMotionListener(mouseMotionListener);


    }

    public WumpusEngine getWumpusEngine(){
        return this.wumpusEngine;
    }

    public void performAfterMoveActions() {
                smallCanvas.repaint();
                canvas.drawHint(-1,-1,-1,-1);   //stop drawing hints
                mouseMotionListener.oldPosX=-1; //condition so when mouse is moved hint will be repainted
    }

    public void addElementToRatioData(float ratio) {
        ratioData.add(ratio);
    }
    public ArrayList<Float> getRatioData(){
        return ratioData;
    }

}
